package com.xiaoyu.lanling.feature.report.data

import `in`.srain.cube.util.internal.AppCallback
import android.annotation.SuppressLint
import android.net.Uri
import android.text.TextUtils
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.app.GlobalUI
import com.xiaoyu.base.net.RequestCreator
import com.xiaoyu.base.utils.ListUtil
import com.xiaoyu.base.utils.upload.UploadImageOriginalType
import com.xiaoyu.base.utils.upload.UploadMediaType
import com.xiaoyu.base.utils.upload.UploadParam
import com.xiaoyu.lanling.R
import com.xiaoyu.lanling.common.config.HttpConfig
import com.xiaoyu.lanling.event.feedback.FeedbackEvent
import com.xiaoyu.lanling.event.report.ReportPreviewListEvent
import com.xiaoyu.lanling.feature.report.datamodels.ReportMediaAddItem
import com.xiaoyu.lanling.feature.report.datamodels.ReportMediaImageItem
import com.xiaoyu.lanling.feature.report.datamodels.ReportMediaItemBase
import com.xiaoyu.lanling.util.upload.UploadCategory
import java.io.File
import java.util.*
import kotlin.collections.ArrayList

class ReportData(private val requestTag: Any, private val objectType: String?, private val reason: String?, private val objectId: String?) {

    private val pictureUriList = ArrayList<Uri>()

    val imageAddAbleCount: Int
        get() = MAX_COUNT_PICTURE - pictureUriList.size

    val pictureBrowseList: List<String>
        get() = ListUtil.convertToList(pictureUriList) { it.toString() }

    fun loadData() {
        notifyPreviewUpdate()
    }

    fun addPicture(uriList: Collection<Uri>) {
        pictureUriList.addAll(uriList)
        if (pictureUriList.size > MAX_COUNT_PICTURE) {
            throw IllegalArgumentException("cannot exceed the limit")
        }
        notifyPreviewUpdate()
    }

    fun removePicture(uri: Uri) {
        pictureUriList.remove(uri)
        notifyPreviewUpdate()
    }

    private fun notifyPreviewUpdate() {
        val previewList = ArrayList<ReportMediaItemBase>()
        var shouldDisplayAddLabel = true

        for (uri in pictureUriList) {
            previewList.add(ReportMediaImageItem(previewList.size, uri.toString()))
        }

        if (previewList.size >= MAX_COUNT_PICTURE) {
            shouldDisplayAddLabel = false
        }

        if (shouldDisplayAddLabel) {
            previewList.add(ReportMediaAddItem(previewList.size))
        }
        ReportPreviewListEvent(previewList).post()
    }

    @SuppressLint("CheckResult")
    fun report(text: String): Boolean {
        val images = LinkedList<String>()
        for (uri in pictureUriList) {
            images.add(File(uri.path).absolutePath)
        }

        if (TextUtils.isEmpty(text)) {
            GlobalUI.getInstance().showToast(AppContext.getString(R.string.report_text_empty_toast))
            return false
        }
        if (ListUtil.isNullOrEmpty(images)) {
            GlobalUI.getInstance().showToast(AppContext.getString(R.string.report_image_empty_toast))
            return false
        }

        UploadParam.batchUpload(images, UploadCategory.REPORT, UploadMediaType.IMAGE, "", UploadImageOriginalType.COMPRESSED, object : AppCallback<List<String>> {
            override fun onSuccess(uploadSuccessUrls: List<String>) {
                submitInternal(text, uploadSuccessUrls)
            }

            override fun onError(e: Throwable) {
                e.printStackTrace()
            }
        })
        return true
    }

    private fun submitInternal(text: String, imageUrlList: List<String>? = ArrayList()) {
        RequestCreator.create<FeedbackEvent>(requestTag, FeedbackEvent::class.java)
                .setRequestUrl(HttpConfig.LANLING_REPORT)
                .setPostEventWhenFail(true)
                .addPostData("objectType", objectType)
                .addPostData("objectId", objectId)
                .addPostData("reason", reason)
                .addPostData("text", text)
                .addPostData("images", TextUtils.join(",", imageUrlList))
                .enqueue()
    }

    companion object {

        private const val MAX_COUNT_PICTURE = 3
        private const val MAX_COUNT_TEXT = 500
    }
}
